home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Devices and Hardware / ATA / ATA Demo / ATA Demo.c next >
Encoding:
Text File  |  2000-09-28  |  22.8 KB  |  807 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        ATA Demo.c
  3.     
  4.     Description:ATADemo is a CodeWarrior C sample that will call the ATA
  5.                  Manager and scan the ATA bus and list the various device
  6.                  configuration data.  
  7.      
  8.                 This sample has been updated to properly work with the .AppleCD
  9.                 driver installed.
  10.  
  11.     Author:        VM
  12.  
  13.     Copyright:     Copyright: © 1996, 1997, 1998,1999 by Apple Computer, Inc.
  14.                 all rights reserved.
  15.     
  16.     Disclaimer:    You may incorporate this sample code into your applications without
  17.                 restriction, though the sample code has been provided "AS IS" and the
  18.                 responsibility for its operation is 100% yours.  However, what you are
  19.                 not permitted to do is to redistribute the source as "DSC Sample Code"
  20.                 after having made changes. If you're going to re-distribute the source,
  21.                 we require that you make it clear in the source that the code was
  22.                 descended from Apple Sample Code, but that you've made changes.
  23.     
  24.     Change History (most recent first):
  25.         06/23/99    Reformatted and Recompiled on CW Pro 2.1(KG)
  26.         
  27.         03/15/99    Updated to CW 4 and it's headers.
  28.                     Added code to set the standard .AppleCD driver
  29.                     into a quiescent state and thus allow us to
  30.                     query the ATA bus without disturbing the .AppleCD driver.(VM)
  31.                         
  32.         06/25/98    Buffer was still the incorrect size in 
  33.                     DisplayATADriveIdentity routine.
  34.                     Buffer needs to be 256 words (for 512 bytes long). 
  35.                     Drive identify just assumes you have allocated a
  36.                     512 byte buffer and writes it accordingly.  In
  37.                     this case it overwrites the end of the array.
  38.  
  39.                     Modified to CW Pro 3 and its headers(VM)
  40.  
  41.  
  42.         10/05/97    Buffer was incorrect size in 
  43.                     DisplayATADriveIdentity routine.
  44.                     Modified to CW Pro 1 and its headers
  45.                     Added Metrowerks SIOUX specific stuff
  46.                     Created Fat application
  47.                     Realized that the words come back swapped; 
  48.                     adjusted for this in the DumpFormatedBuffer routine.(BLoB)
  49.     
  50.  
  51. */
  52.  
  53.  
  54. //------------------------------------------------------------------------------------
  55. #pragma mark Includes
  56. //------------------------------------------------------------------------------------
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <LowMem.h>
  60. #include <Patches.h>
  61. #include <Traps.h>
  62. #include <Devices.h>
  63.  
  64. #include <ATA.h>
  65. #ifdef __MWERKS__
  66.     #include <SIOUX.h>
  67. #endif
  68. #include "ata_powerpc.h"
  69. //------------------------------------------------------------------------------------
  70. #pragma mark Defines
  71. //------------------------------------------------------------------------------------
  72.  
  73. //
  74. // Identifies the bus protocol type.
  75. //
  76.  
  77. enum {
  78.     kDevUnknown        =    0,
  79.     kDevATA            =    1,
  80.     kDevATAPI        =    2,
  81.     kDevPCMCIA        =    3
  82. };
  83.  
  84. //
  85. // Identifies the Socket type.
  86. //
  87. enum {
  88.     kSocketUnknown        =    0,
  89.     kSocketInternal        =    1,
  90.     kSocketMediaBay        =    2,
  91.     kkSocketPCMCIA        =    3
  92. };
  93.  
  94.  
  95. // .AppleCD contants 
  96. enum
  97.     {
  98.     csSetPowerMode    =    70,
  99.     csQuiescence    =    0x437
  100.     };
  101.  
  102. enum
  103.     {
  104.     pmActive        =    0,
  105.     pmStandby        =    1,
  106.     pmIdle            =    2,
  107.     pmSleep            =    3
  108.     };
  109.  
  110. enum
  111.     {
  112.     quiescenceON    =    0,
  113.     quiescenceOFF    =    1
  114.     };
  115.  
  116.  
  117. //------------------------------------------------------------------------------------
  118. #pragma mark Macros
  119. //------------------------------------------------------------------------------------
  120.  
  121. #define CLEAR(what) do {                        \
  122.         register Ptr        _ptr = (Ptr) &what;    \
  123.         register Size        _len = sizeof what;    \
  124.         for (; _len > 0; --_len)                    \
  125.             *_ptr++ = 0;                        \
  126.     } while (0)
  127.  
  128. #define IF_ERROR(_err_,_str_) if (_err_ != noErr) { printf(_str_); return (_err_); }
  129.  
  130.  
  131. //------------------------------------------------------------------------------------
  132. #pragma mark -
  133.  
  134. //------------------------------------------------------------------------------------
  135. #pragma mark Identify Drive Info
  136. //------------------------------------------------------------------------------------
  137.  
  138. //
  139. //  Bit fields returned from Identify Drive command
  140. //
  141. enum {
  142.     magdrv_bit        =    15,            /* WORD 0: bit number of mag drive indicator    */
  143.     rcd_bit            =    7,            /* WORD 0: bit number of removable indicator    */
  144.     fixed_bit        =    6,            /* WORD 0: bit number of fixed disk indicator    */
  145.  
  146.     lbamode_bit        =    9,            /* bit number of lba support indicator            */
  147.     iordy_bit        =    11,            /* bit number of IORDY support indicator        */
  148.     extvalid_bit    =    1,            /* bit number of valid extension word            */
  149.     mode3_bit        =    0,            /* WORD 64: bit number of mode 3 support        */
  150.     
  151.     kMagDrv            =    1 << magdrv_bit,    /* Bit 15 = 0 -> a magnetic drive        */
  152.     kRemovable        =    1 << rcd_bit,        /* Bit 7 != 0 -> removable cartridge    */
  153.     kFixed            =    1 << fixed_bit,        /* Bit 6 != 0 -> indicates fixed drive    */
  154.     kLBAMode        =    1 << lbamode_bit,    /* LBA support indicator                */
  155.     kIORDY            =    1 << iordy_bit,        /* IORDY support indicator                */
  156.     kExtValid        =    1 << extvalid_bit,    /* Extension word valid                    */
  157.     MODE3BIT        =    1 << mode3_bit        /* mode 3 bit in word 64 of ident data    */
  158. };
  159.  
  160. //
  161. // This is returned by the device in response to an IDENTIFY command (512 bytes).
  162. //
  163. typedef    struct IdentifyBlock {    /* Structure of Identify data                        */
  164.     short    Signature;            /* Word 00: Constant value                            */
  165.     short    NumCyls;            /* Word 01:    Number of cylinders (default mode)            */
  166.     short    RSVD0;                /* Word 02:    Constant value of 0                        */
  167.     short    NumHds;                /* Word 03:    Number of heads (default mode)            */
  168.     short    TrkBytes;            /* Word 04:    Number of unformatted bytes/track        */
  169.     short    SecBytes;            /* Word 05:    Number of unformatted bytes/sector        */
  170.     short    NumSecs;            /* Word 06:    Number of sectors/track                    */
  171.     short    VU0;                /* Word 07:    Vendor unique                            */
  172.     short    VU1;                /* Word 08:    Vendor unique                            */
  173.     short    VU2;                /* Word 09:    Vendor unique                            */
  174.     short    Serial[10];            /* Word 10-19:    Serial Number (right-justified)        */
  175.     short    BufType;            /* Word 20:    Buffer Type                                */
  176.     short    BufSize;            /* Word 21:    Buffer size in 512 byte increments        */
  177.     short    NumECC;                /* Word 22:    Number of ECC bytes                        */
  178.     short    FirmRev[4];            /* Word 23-26:    Firmware revision (left-justified)    */
  179.     short    ModelNum[20];        /* Word 27-46:    Model number (left-justified)        */
  180.     short    MultCmds;            /* Word 47:    R/W multiple commands not impl = 0        */
  181.     short    DblXferFlag;        /* Word 48:    Double transfer flag                    */
  182.     short    Capabilities;        /* Word 49: LBA, DMA, IORDY support indicator        */
  183.     short    Reserved1;            /* Word 50: Reserved                                */
  184.     short    PIOTiming;            /* Word 51: PIO transfer timing mode                */
  185.     short    DMATiming;            /* Word 52:    DMA transfer timing mode                */
  186.     short    Extension;            /* Word 53: extended info support                    */
  187.     short    CurCylinders;        /* Word 54: number of current cylinders                */
  188.     short    CurHeads;            /* Word 55: number of current heads                    */
  189.     short    CurSPT;                /* Word 56: number of current sectors per track        */
  190.     short    CurCapacity[2];        /* Word 57-58: current capacity in sectors            */
  191.     short    MultSectors;        /* Word 59: Multiple sector setting                    */
  192.     short    LBACapacity[2];        /* Word 60-61: total sectors in LBA mode            */
  193.     short    SWDMA;                /* Word 62: single word DMA support                    */
  194.     short    MWDMA;                /* Word 63: multi word DMA support                    */
  195.     short    APIOModes;            /* Word 64:    Advanced PIO Xfr mode supported            */
  196.     short    MDMATiming;            /* Word 65:    Minimum Multiword DMA Xfr Cycle            */
  197.     short    RDMATiming;            /* Word 66:    Recommended Multiword DMA Cycle            */
  198.     short    MPIOTiming;            /* Word 67:    Min PIO XFR Time W/O Flow Control        */
  199.     short    PIOwRDYTiming;        /* Word 68:    Min PIO XFR Time with IORDY flow ctrl    */
  200.     short    Reserved[187];        /* Word 69-255: Reserved                            */
  201. } IdentifyBlock;
  202.  
  203. //
  204. // The following structure and table simplifies the formatting.
  205. //
  206. enum {
  207.     kEndOfTable = 0,            /* Marker                                            */
  208.     kDecimal,                    /* Signed integer (two words are high..low)            */
  209.     kHex,                        /* Bitfield                                            */
  210.     kLeftJust,                    /* Ascii, left-justified, space padded                */
  211.     kRightJust                    /* Ascii, right-justified, space padded                */
  212. };
  213. struct FormatTable {
  214.     short        firstWord;        /* First word in IdentifyBlock cast to short vector    */
  215.     short        lastWord;        /* Last word in IdentifyBlock cast to short vector    */
  216.     short        format;            /* Format from above enum                            */
  217.     const char    *label;            /* Text to display                                    */
  218. };
  219.  
  220. typedef struct FormatTable FormatTable, *FormatTablePtr;
  221.  
  222. FormatTable kIdentFormat[] = {
  223.     {     0,     0, kHex,        "Configuration word"                        },
  224.     {     1,     1,    kDecimal,    "Cylinders"            },
  225.     {     3,     3,    kDecimal,    "Heads"                },
  226.     {     4,     4,    kDecimal,    "Bytes/Track"            },
  227.     {     5,     5,    kDecimal,    "Bytes/Sector (0 = 512 bytes)"        },
  228.     {     5,     5,    kDecimal,    "Sectors/Track"        },    /* 35 */
  229.     {     7,     9,    kHex,        "Vendor Unique (word 7..9)"                    },
  230.     {    10,    19,    kRightJust,    "Serial Number"                                },
  231.     {    20,    20,    kHex,        "Buffer Type"                                },
  232.     {    21,    21,    kDecimal,    "Buffer size in 512 byte increments"        },
  233.     {    22,    22,    kDecimal,    "Number of ECC bytes available"                },
  234.     {    23,    26,    kLeftJust,    "Firmware Revision"                            },
  235.     {    27,    46,    kLeftJust,    "Model Number"                                },
  236.     {    47,    53,    kHex,        "Capability Flags (word 47..53)"            },
  237.     {    54,    54,    kDecimal,    "Cylinders (current mode)"        },
  238.     {    55,    55,    kDecimal,    "Heads (current mode)"            },
  239.     {    56,    56,    kDecimal,    "Sectors/Track (current mode)"        },
  240.     {    57,    58,    kDecimal,    "Current Capacity in Sectors"                },
  241.     {    59,    59,    kHex,        "Multiple Sector Capability Flag"            },
  242.     {    60,    61,    kDecimal,    "Current User-addressable Sectors"            },
  243.     {    62,    62,    kHex,        "Single Word DMA Transfer Mode Flags"        },
  244.     {    63,    63,    kHex,        "Multiword DMT Transfer Mode Flags"            },
  245.     {     0,  0,    kEndOfTable,""                                            }
  246. };
  247.  
  248.  
  249.  
  250. //------------------------------------------------------------------------------------
  251. #pragma mark Prototypes
  252. //------------------------------------------------------------------------------------
  253.  
  254. Boolean     ATAManagerPresent    (void);
  255. Boolean     ATAHardwarePresent    (void);
  256. Boolean     TrapAvailable        (short theTrap);
  257. void         PrintNumVersion        (char *label, NumVersion version );
  258. OSErr         DisplayATAManagerInquiryInfo (void);
  259.  
  260. OSErr         ScanATABusses         (void);
  261. OSErr         DisplayATADriveIdentity (UInt32 deviceID );
  262. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length );
  263. void        DumpFormatedBuffer    (void* p, const  FormatTablePtr formatPtr);
  264. char*        DrvrRefToName        (short refNum);
  265.  
  266. OSErr         DisableCDDriver     (SInt16 refNum);
  267. OSErr         EnableCDDriver         (SInt16 refNum);
  268. OSErr         WakeUpCDDrive         (SInt16 refNum);
  269. OSErr         SetQuiescence         (SInt16 refNum, UInt16 mode);
  270.  
  271.  
  272. //------------------------------------------------------------------------------------
  273. #pragma mark -
  274.  
  275.  
  276. // ---------------------------------------------------------------------------
  277. void     main     (void)
  278. // ---------------------------------------------------------------------------
  279. {
  280.     OSErr            status;
  281.     SInt16            drvrRefNum  = 0;
  282.     
  283. #ifdef __MWERKS__
  284.     SIOUXSettings.asktosaveonclose = false;
  285. #endif
  286.  
  287.     printf("Macintosh ATA Manager Sample\n\n");
  288.  
  289. // Check for ATA Hardware 
  290. // you should do this before calling the ATAManager, since some early ROMS
  291. // could indicate an ATA manager without the proper HW, thus casing a crash.
  292.     if (ATAHardwarePresent() == false) {
  293.         printf("ATA Hardware is not present on this system\n");
  294.         exit(EXIT_FAILURE);
  295.     }
  296.  
  297. // Check for ATA Manager
  298.     if (ATAManagerPresent() == false) {
  299.         printf("ATA Manager is not present on this system\n");
  300.         exit(EXIT_FAILURE);
  301.     }
  302.         
  303. // Display ATA Manager Info
  304.     status = DisplayATAManagerInquiryInfo();
  305.     if (status != noErr) {
  306.         printf("Cannot access ATA Manager: %d\n", (int) status);
  307.         exit(EXIT_FAILURE);
  308.     }
  309.  
  310. // Disable the CD driver 
  311.     status = OpenDriver("\p.AppleCD", &drvrRefNum);    
  312.     if (status == noErr) {
  313.         printf("Found .AppleCD driver, preparing to disable it\n");
  314.         status = DisableCDDriver(drvrRefNum);
  315.      }
  316.     
  317. // Display ATA Device Info
  318.     status = ScanATABusses();
  319.     if (status != noErr) {
  320.         printf("Cannot access ATA Manager: %d\n", (int) status);
  321.         exit(EXIT_FAILURE);
  322.     }
  323.     
  324. // Renable the CD driver
  325.     if(drvrRefNum != 0)
  326.     {
  327.         printf("Re-enabling the .AppleCD driver \n");
  328.         status = EnableCDDriver(drvrRefNum);
  329.     }
  330.     
  331.     
  332. }
  333.  
  334.  
  335. // ---------------------------------------------------------------------------
  336. OSErr         DisplayATAManagerInquiryInfo (void)
  337. // ---------------------------------------------------------------------------
  338. //
  339. //  Display information about the ATA Manager
  340. //
  341. {
  342.     ataMgrInquiry    pb;
  343.     OSErr            status;
  344.  
  345.     CLEAR(pb);
  346.     
  347.     pb.ataPBFunctionCode =    kATAMgrManagerInquiry;
  348.     pb.ataPBVers =            kATAPBVers1;
  349.  
  350.     status = ataManager((ataPB*) &pb );
  351.     IF_ERROR(status, "ATA Manager Inquiry failed\n")
  352.  
  353.     printf("ATA Manager inquiry:\n");
  354.     PrintNumVersion("\tATA Manager Version:", pb.ataMgrVersion);
  355.     printf("\tBusses:\t\t%d\n\tDevices:\t%d\n",
  356.                 pb.ataBusCnt, pb.ataDevCnt);
  357.     printf("\tPIO Modes:\t%x\n\tDMA Modes:\t%d\n\tMulti DMA Modes:%x\n",
  358.                  pb.ataPioModes, pb.ataSingleDMAModes, pb.ataMultiDMAModes);
  359.     printf("-----------------------------------------\n\n");    
  360.     return (status);
  361. }
  362.  
  363.  
  364. // ---------------------------------------------------------------------------
  365. OSErr         ScanATABusses (void)
  366. // ---------------------------------------------------------------------------
  367. //
  368. //  Display information about the ATA Busses
  369. //
  370. {
  371.     ataDrvrRegister        pb;
  372.     OSErr                status;
  373.  
  374. // Get first device ID (yes you have to do this once)
  375.     CLEAR(pb);
  376.     pb.ataPBFunctionCode     =    kATAMgrFindDriverRefnum;
  377.     pb.ataPBVers            =    kATAPBVers1;
  378.     pb.ataPBDeviceID         =     (UInt32)0x0000ffff;
  379.     status                     =     ataManager((ataPB*) &pb );
  380.  
  381. // loop through devices
  382.     for    (pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID;
  383.          pb.ataPBDeviceID != 0xff;
  384.          pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID)
  385.         {             
  386.             status = ataManager((ataPB*) &pb );
  387.             IF_ERROR(status, "ATA Find Driver failed\n")
  388.             
  389.             printf("\nDevice %d %#s\n", pb.ataPBDeviceID, DrvrRefToName(pb.ataDrvrRefNum) );
  390.             DisplayATADriveIdentity(pb.ataPBDeviceID);
  391.             
  392.         printf("-----------------------------------------\n");    
  393.         };    
  394.     
  395.     printf("\n");    
  396.     return (status);
  397. }
  398.  
  399.  
  400.  
  401. // ---------------------------------------------------------------------------
  402. OSErr         DisplayATADriveIdentity (UInt32 deviceID)
  403. // ---------------------------------------------------------------------------
  404. //
  405. //  Display information about the ATA Identify Info
  406. //
  407. {
  408.     ataIdentify            pb;
  409.     ataDevConfiguration    pb1;
  410.     
  411.     UInt16        buffer[256];
  412.     OSErr        status;
  413.     
  414.  
  415. // Get Driver Configuration
  416.     CLEAR(pb1);
  417.     pb1.ataPBFunctionCode     =    kATAMgrGetDrvConfiguration;
  418.     pb1.ataPBVers            =    kATAPBVers2;
  419.     pb1.ataPBDeviceID         =    deviceID;
  420.     
  421.     status = ataManager((ataPB*) &pb1 );
  422.     IF_ERROR(status, "ATA GetDrvConfiguration failed\n")
  423.  
  424.  
  425. // Setup Identify block;
  426.     CLEAR(pb);
  427.     pb.ataPBFunctionCode     =    kATAMgrDriveIdentify;
  428.     pb.ataPBVers            =    kATAPBVers1;
  429.     pb.ataPBDeviceID        =    deviceID;
  430.      pb.ataPBFlags             =     mATAFlagIORead + mATAFlagByteSwap ;
  431.      
  432.      if(pb1.ataDeviceType == kDevATAPI) pb.ataPBFlags += mATAFlagProtocol1;
  433.      
  434.     pb.ataPBTimeOut            =    100;
  435.     pb.ataPBBuffer            =    (void*) buffer;
  436.     
  437.     status = ataManager((ataPB*) &pb );
  438.     IF_ERROR(status, "ATA DriveIdentify failed\n")
  439.  
  440.     printf("Configuration: (");
  441.  
  442.     switch(pb1.ataDeviceType){
  443.         case kDevUnknown:    
  444.                         printf("Unknown protocol"); 
  445.                         break;
  446.         
  447.         case kDevATA:
  448.                         printf("ATA"); 
  449.                         break;
  450.                              
  451.         case kDevATAPI:    
  452.                         printf("ATAPI"); 
  453.                         break;
  454.                         
  455.         case kDevPCMCIA:    
  456.                         printf("PCMCIA"); 
  457.                         break;
  458.     }
  459.     
  460.     switch(pb1.ataSocketType){
  461.         case kSocketUnknown:    
  462.                         printf(", Unknown Socket"); 
  463.                         break;
  464.         
  465.         case kSocketInternal:
  466.                         printf(", Internal"); 
  467.                         break;
  468.                              
  469.         case kSocketMediaBay:    
  470.                         printf(", Media Bay"); 
  471.                         break;
  472.                         
  473.         case kkSocketPCMCIA:    
  474.                         printf(", PCMCIA, Vcc=%d, Vpp1=%d, Vpp2=%d", 
  475.                                         pb1.atapcVcc, pb1.atapcVpp1,pb1.atapcVpp2); 
  476.                         break;
  477.     }
  478.  
  479.     printf(")\n");
  480.  
  481.     DumpFormatedBuffer(buffer, kIdentFormat);
  482.     return noErr;
  483. }
  484.  
  485.  
  486.  
  487. // ---------------------------------------------------------------------------
  488. OSErr         DisableCDDriver (SInt16 refNum)
  489. // ---------------------------------------------------------------------------
  490. //
  491. // Disable the CD driver
  492. //
  493. {    OSErr status;
  494.     printf("- Disable the CD Driver \n");
  495.  
  496.      // wake up drive
  497.     status = WakeUpCDDrive (refNum);
  498.     if (status != noErr)
  499.     {
  500.         return status;
  501.     }
  502.  
  503.     // move driver to quiescent mode
  504.     status = SetQuiescence (refNum, quiescenceON);
  505.     if (status != noErr)
  506.     {
  507.         return status;
  508.     }
  509.  
  510.     return noErr;
  511. }
  512.  
  513. // ---------------------------------------------------------------------------
  514. OSErr         EnableCDDriver (SInt16 refNum)
  515. // ---------------------------------------------------------------------------
  516. //
  517. //  Re-enable the CD driver
  518. //
  519. {    OSErr status;
  520.  
  521.     printf("- Enable the CD Driver \n");
  522.  
  523.     // move driver to quiescent mode
  524.     status = SetQuiescence (refNum, quiescenceOFF);
  525.     if (status != noErr)
  526.     {
  527.         return status;
  528.     }
  529.  
  530.     return noErr;
  531. }
  532.  
  533. // ---------------------------------------------------------------------------
  534. OSErr         WakeUpCDDrive (SInt16 refNum)
  535. // ---------------------------------------------------------------------------
  536. //
  537. //  Re-enable the CD driver
  538. //
  539. {    CntrlParam    pb;
  540.     OSErr        status;
  541.  
  542.     printf("-- Wake up the CD Driver \n");
  543.  
  544.     CLEAR(pb);
  545.  
  546.      pb.ioCRefNum = refNum;
  547.     pb.csCode = csSetPowerMode;
  548.     *(UInt8 *) &pb.csParam[0] = pmActive;
  549.     
  550.   // send command to the CD/DVD driver
  551.     status = PBControlImmed ((ParmBlkPtr) &pb);
  552.  
  553.      return status;
  554. }
  555.  
  556. // ---------------------------------------------------------------------------
  557. OSErr         SetQuiescence (SInt16 refNum, UInt16 mode)
  558. // ---------------------------------------------------------------------------
  559. //
  560. //  Re-enable the CD driver
  561. //
  562. {
  563.     CntrlParam    pb;
  564.     OSErr        status;
  565.  
  566.     printf("-- Set the CD Driver Quiescence mode to %s\n",  
  567.         (mode ==quiescenceOFF)? "Off":"On");
  568.  
  569.     CLEAR(pb);
  570.  
  571.      pb.ioCRefNum = refNum;
  572.     pb.csCode = csQuiescence;
  573.     pb.csParam[0] = mode;
  574.     
  575.   // send command to the CD/DVD driver
  576.     status = PBControlImmed ((ParmBlkPtr) &pb);
  577.  
  578.      return status;
  579. }
  580.  
  581.  
  582. // ---------------------------------------------------------------------------
  583. Boolean     ATAManagerPresent    (void)
  584. // ---------------------------------------------------------------------------
  585. //
  586. // returns true if this machine has the ata manager
  587. //
  588. {
  589.         return (TrapAvailable(kATATrap));
  590. }
  591.  
  592. // ---------------------------------------------------------------------------
  593. Boolean     ATAHardwarePresent        (void)
  594. // ---------------------------------------------------------------------------
  595. //
  596. // returns true if this machine has ata hardware
  597. //
  598. {
  599.     UInt16    configFlags;
  600.  
  601.     // Hardware configuration flags
  602.     configFlags = LMGetHWCfgFlags();
  603.     
  604.     return (configFlags & 0x0080);
  605. }
  606.  
  607. //------------------------------------------------------------------------------------
  608. #pragma mark -
  609.  
  610. #define NumToolboxTraps() (                                \
  611.         (NGetTrapAddress(_InitGraf, ToolTrap)            \
  612.                 == NGetTrapAddress(0xAA6E, ToolTrap))    \
  613.             ? 0x200 : 0x400                                \
  614.     )
  615. #define GetTrapType(theTrap) (                            \
  616.         (((theTrap) & 0x800) != 0) ? ToolTrap : OSTrap    \
  617.     )
  618.  
  619. // ---------------------------------------------------------------------------
  620. Boolean     TrapAvailable        (short theTrap)
  621. // ---------------------------------------------------------------------------
  622. // (see Inside Mac VI 3-8)
  623. {
  624.         TrapType                trapType;
  625.         
  626.         trapType = GetTrapType(theTrap);
  627.         if (trapType == ToolTrap) {
  628.             theTrap &= 0x07FF;
  629.             if (theTrap >= NumToolboxTraps())
  630.                 theTrap = _Unimplemented;
  631.         }
  632.         return (
  633.             NGetTrapAddress(theTrap, trapType)
  634.             != NGetTrapAddress(_Unimplemented, ToolTrap)
  635.         );
  636. }
  637.  
  638. // ---------------------------------------------------------------------------
  639. void         PrintNumVersion        (char *label, NumVersion version )
  640. // ---------------------------------------------------------------------------
  641. //
  642. //    Decode version number info
  643. //
  644. {
  645.     char            *stage;
  646.  
  647.     switch (version.stage) {
  648.     case developStage:    stage = "d";        break;
  649.     case alphaStage:    stage = "a";        break;
  650.     case betaStage:        stage = "b";        break;
  651.     case finalStage:    stage = "";            break;
  652.     default:            stage = "?";        break;
  653.     
  654.     }
  655.     printf("%s %d.%d.%d",
  656.         label,
  657.         version.majorRev,
  658.         (version.minorAndBugRev>>4), (version.minorAndBugRev & 0xf),
  659.         stage);
  660.     if(version.stage != finalStage) printf(".%d",version.nonRelRev);
  661.     
  662.     printf(" (hex %08lx)\n",    (* ((unsigned long *) &version)));
  663. }
  664.  
  665.  
  666.  
  667. // ---------------------------------------------------------------------------
  668. void        DumpFormatedBuffer    (void* p,  const FormatTablePtr format) 
  669. // ---------------------------------------------------------------------------
  670. //
  671. // Dump formatted buffer
  672. //
  673.  
  674. {    
  675.     unsigned short            *idInfo = p;
  676.          
  677.     register char            *charField;
  678.     register short            fieldLength;
  679.     register short            i;
  680.     register long            value;
  681.     register FormatTablePtr    formatPtr;
  682.     
  683. #define FORMAT    (*formatPtr)
  684.  
  685.     for (formatPtr = format; FORMAT.format != kEndOfTable; formatPtr++) {
  686.             printf("%35s", FORMAT.label);
  687.             switch (FORMAT.format) {
  688.             // Decimal values come as two words with the words swapped.
  689.             case kDecimal:
  690.                 value = 0;
  691.                 for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
  692.                     value <<= 16;
  693.                     value += idInfo[i];
  694.                 }
  695.                 printf(" %lu", value);    // was %lu
  696.                 break;
  697.             case kHex:
  698.                 for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
  699.                     value = idInfo[i];
  700.                     printf(" %04ld", value);
  701.                 }
  702.                 break;
  703.             case kLeftJust:
  704.                 charField = (char *) &idInfo[FORMAT.firstWord];
  705.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  706.                             * sizeof (unsigned short);
  707.                 /*
  708.                  * First scan for an unspecified field.
  709.                  */
  710.                 for (i = 0; i <= fieldLength; i++) {
  711.                     if (charField[i] != '\0')
  712.                         goto gotLeftJustField;
  713.                 }
  714.                 printf(" <not specified>");
  715.                 break;
  716. gotLeftJustField:
  717.                 for (i = fieldLength; i > 0; --i) {
  718.                     if (charField[i - 1] != ' ')
  719.                         break;
  720.                 }
  721.                 printf(" \"%.*s\"", (int) i, charField);
  722.                 break;
  723.             case kRightJust:
  724.                 charField = (char *) &idInfo[FORMAT.firstWord];
  725.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  726.                             * sizeof (unsigned short);
  727.                 /*
  728.                  * First scan for an unspecified field.
  729.                  */
  730.                 for (i = 0; i <= fieldLength; i++) {
  731.                     if (charField[i] != '\0')
  732.                         goto gotRightJustField;
  733.                 }
  734.                 printf(" <not specified>");
  735.                 break;
  736. gotRightJustField:
  737.                 for (i = 0; i < fieldLength; i++) {
  738.                     if (charField[i] != ' ')
  739.                         break;
  740.                 }
  741.                 printf(" \"%.*s\"", (int) (fieldLength - i), &charField[i]);
  742.                 break;
  743.             }
  744.             printf("\n");
  745.         }
  746. //        DumpRawBuffer( p,512);
  747. }    
  748.     
  749. // ---------------------------------------------------------------------------
  750. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length )
  751. // ---------------------------------------------------------------------------
  752. //
  753. // Dump buffer
  754. //
  755.  
  756. {
  757.         register int            i;
  758.         int                        lineStart;
  759.         int                        lineLength;
  760.         short                    c;
  761.  
  762. #define kLineSize    16
  763.         for (lineStart = 0; lineStart < length; lineStart += lineLength) {
  764.             lineLength = kLineSize;
  765.             if (lineStart + lineLength > length)
  766.                 lineLength = length - lineStart;
  767.             printf("%03x %3d:", lineStart, lineStart);
  768.             for (i = 0; i < lineLength; i++)
  769.                 printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
  770.             for (; i < kLineSize; i++)
  771.                 printf("   ");
  772.             printf("  ");
  773.             for (i = 0; i < lineLength; i++) {
  774.                 c = bufferPtr[lineStart + i] & 0xFF;
  775.                 if (c > ' ' && c < '~')
  776.                     printf("%c", c);
  777.                 else {
  778.                     printf(".");
  779.                 }
  780.             }
  781.             printf("\n");
  782.         }
  783. }
  784.  
  785.  
  786.         
  787. // ---------------------------------------------------------------------------
  788. char*        DrvrRefToName(short refNum)
  789. // ---------------------------------------------------------------------------
  790. //
  791. //  lookup driver name in table
  792. //
  793.  
  794. {
  795.         AuxDCEHandle*        UTable  = (AuxDCEHandle*) LMGetUTableBase();
  796.         DCtlPtr                dctl;
  797.         Ptr                    p;    
  798.         
  799.         if(!refNum) return ((char*) "\p<none>");
  800.  
  801.         dctl = (DCtlPtr) *UTable[~refNum];
  802.         p      =  dctl->dCtlDriver;
  803.         if( dctl->dCtlFlags  & 0x0040) p = (void*) *p;
  804.  
  805.         return  ( p?(char*) (p+18):(char*)"\p-Purged-");
  806. }
  807.